package com.ht.api.call.func.impl;

import java.util.List;

import javax.sql.DataSource;

import com.ht.api.bean.AjaxResult;
import com.ht.api.bean.LoginBean;
import com.ht.api.call.func.IFunctionCall;
import com.ht.api.db.Db;
import com.ht.api.db.Entity;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.hlink.Hlink;
import com.ht.api.db.task.HtTaskExecutor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 执行hlink
 * 传入映射关系表中的main_id，然后找到映射关系，
 * 并通过source_id和source_table_code找到对应的源数据，然后将所有对应的源数据，跑一遍hlink到目标表
 * @author asq
 * @createTime 2025年2月10日 13:51:25
 */
@Slf4j
public class HlinkFunctionCall implements IFunctionCall {
	@Override
	public String getName() {
		return "执行hlink";
	}

	@Override
	public JSONObject execute(LoginBean me, JSONObject param, AjaxResult result) {
		// 获取映射关系hlink_relation
		Long relationId = param.getLong("relation_id");
		if (relationId == null) {
			throw new HtException("请指定映射关系ID参数：relation_id");
		}
		Entity relation = Db.createSqlParser("hlink_relation").findById(relationId);
		if (relation == null) {
			throw new HtException("映射关系不存在，ID：" + relationId);
		}
		
		// 获取hlink_relation的配置
		String sourceId = relation.getStr("source_id");
		String sourceTableCode = relation.getStr("source_table_code");
		long tenantId = me.getTenantId();
		DataSource ds = me.getDataSource();
		
		// 根据hlink_relation的配置，获取源数据
		String table = StrUtil.isNotBlank(sourceTableCode) ? sourceTableCode : "open_data";
		List<Entity> dataList = null;
		if (StrUtil.isNotBlank(sourceTableCode)) {
			dataList = Db.createSqlParser(sourceTableCode).query(ds);
		} else if (StrUtil.isNotBlank(sourceId)) {
			Entity hlinkSource = Db.createSqlParser("hlink_source").findById(sourceId);
			String sourceCode = hlinkSource.getStr("code");
			dataList = Db.createSqlParser("open_data").where("source_code", sourceCode).query(ds);
		} else {
			throw new HtException("映射关系配置有误，无法进行Hlink处理，ID：" + relationId);
		}
		
		// 将源数据扔给Hlink进行处理
		List<Entity> finalDataList = dataList;
		if (finalDataList.isEmpty()) {
			throw new HtException("源数据为空，不进行Hlink处理~");
		} else {
			HtTaskExecutor.execute(() -> {
				log.info("[HlinkFunctionCall]执行Hlink流程开始，租户ID：{}，源表：{} 源数据条数：{}", tenantId, table, finalDataList.size());
				Hlink.execute(ds, table, finalDataList);
				log.info("[HlinkFunctionCall]执行Hlink流程结束，租户ID：{}，源表：{} 源数据条数：{}", tenantId, table, finalDataList.size());
			});
		}
		
		return JSONUtil.createObj();
	}

}
